#pragma once
#ifndef __LIT__VERSION_INCLUDED__HH__
#define __LIT__VERSION_INCLUDED__HH__

#include "..\LitProjectVersion.h"
#include <LitExport.hpp>
#include <LitString.h>
#include <sstream>

namespace Lit
{
	template<typename TraitsType = int>
	struct LIT_API Version
	{
		typename typedef TraitsType Traits;

	public:
		Version( Traits maj = Major, Traits min = Minor, Traits build = Build, Traits rev = Revision ) 
			: mMajor(maj), mMinor(min), mBuild(build), mRevision(rev)
		{}
		Version(const Version& rk) 
			: mMajor(rk.mMajor), mMinor(rk.mMinor), mBuild(rk.mBuild), mRevision(rk.mRevision)
		{}
		~Version() {}
		
		const Traits& major() const{ return mMajor; }
		const Traits& minor() const{ return mMinor; }
		const Traits& build() const{ return mBuild; }
		const Traits& revision() const{ return mRevision; }
		
		static const Traits Major=PROJECT_VERSION_MAJOR;
		static const Traits Minor=PROJECT_VERSION_MINOR;
		static const Traits Build=PROJECT_VERSION_BUILD;
		static const Traits Revision=PROJECT_VERSION_REVISION;

		String& replaceFmtParam( String &in, const String &param, Traits value ) const
		{
			size_t p = in.find(param);
			if( p==String::npos ) return in;
#ifdef LIT_UNICODE
			std::wstringstream ss;
#else
			std::stringstream ss;
#endif
			ss << value;
			return in.replaceAll(param, ss.str().c_str(), true);
		}
		String toString( const String &fmt = "M.m.b.r" ) const
		{
			String ret(fmt);
			ret = replaceFmtParam( ret, "M", major() );
			ret = replaceFmtParam( ret, "m", minor() );
			ret = replaceFmtParam( ret, "b", build() );
			ret = replaceFmtParam( ret, "r", revision() );
			return ret;
		}
		
	protected:
		Traits mMajor, mMinor, mBuild, mRevision;
	};
};

LIT_API_C std::ostream& operator << ( std::ostream &strm, const Lit::Version<> & vers );

#endif